package com.dc.diffutil

import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.AsyncListDiffer
import androidx.recyclerview.widget.RecyclerView

abstract class AsyncListDifferAdapter<T>(
    private val context: Context,
    private var layoutId: Int
) :
    RecyclerView.Adapter<ViewHolder>() {

    private var mTypeSupport: MulitiTypeSupport<T>? = null

    var mItemClick: ((Int, T) -> Unit)? = null
    var mItemLongClick: ((Int, T) -> Boolean)? = null

    private val asyncListDiffer by lazy {
        createAsyncListDiffer()
    }

    constructor(context: Context, typeSupport: MulitiTypeSupport<T>?) : this(
        context,
        -1
    ) {
        mTypeSupport = typeSupport
    }


    override fun getItemCount(): Int {
        return asyncListDiffer.currentList.size
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        mTypeSupport?.let {
            layoutId = viewType
        }
        val itemView = LayoutInflater.from(context).inflate(layoutId, parent, false)
        return ViewHolder(itemView)
    }

    /**
     * 会先执行三个参数的onBindViewHolder，再执行两个参数的onBIndViewHolder，如果有公共逻辑，写在commonConvert方法中
     */
    override fun onBindViewHolder(holder: ViewHolder, position: Int, payloads: MutableList<Any>) {
        if (payloads.isEmpty()) {
            super.onBindViewHolder(holder, position, payloads)
        } else {
            convert(holder, payloads[0] as Bundle, position)
        }
        getItem(position).run {
            commonConvert(holder, this, position)
        }
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        getItem(position).run {
            convert(holder, this, position)
        }
    }

    private fun getItem(position: Int) = asyncListDiffer.currentList[position]

    override fun getItemViewType(position: Int): Int {
        return mTypeSupport?.getLayoutId(getItem(position)) ?: super.getItemViewType(position)
    }

    public fun setData(dataList: List<T>) {
        asyncListDiffer.submitList(dataList)
    }

    abstract fun createAsyncListDiffer(): AsyncListDiffer<T>

    /**
     * 2个/3个 onBindViewHolder的公共逻辑
     */
    open fun commonConvert(holder: ViewHolder, t: T, position: Int) {
        getItem(position).run {
            holder.itemView.setOnClickListener {
                mItemClick?.invoke(position, this)
            }
            holder.itemView.setOnLongClickListener {
                mItemLongClick?.invoke(position, this) ?: false
            }
        }
    }

    /**
     * 对应2个参数onBindViewHolder方法的数据绑定
     */
    abstract fun convert(holder: ViewHolder, t: T, position: Int)

    /**
     * ItemCallback中覆写了getChangePayload方法则需要覆写该方法，配合三个参数的onBindViewHolder实现控件级别刷新
     */
    open fun convert(holder: ViewHolder, bundle: Bundle, position: Int) {

    }
}